import 'dart:async';
import 'dart:typed_data';

import 'package:bluetooth_ble/bluetooth_ble.dart';
import 'package:bluetooth_spp/bluetooth_spp.dart';
import 'package:flutter/cupertino.dart';
import 'package:sxw_bluetooth_provider/src/config/config.dart';

import 'platform_enum.dart';

part 'sxw_spp_device.dart';

part 'sxw_ble_device.dart';

//typedef R BtTransformer<R, T>(T data);

abstract class BtTransformer<R, T> {
  const BtTransformer();

  T convert(R value);
}

abstract class SxwBluetoothDevice<Device, RecData, WriteData> {
  String get name;

  String debugLabel;

  Device device;

  String get id;

  bool canUse = false;

  PlatformEnum get platformEnum => config?.platformTypeEnum;

  String get deviceType {
    return "<${config?.btType},${config.platformType}>";
  }

  BluetoothConnectConfig<WriteData> get config;

  BtTransformer<WriteData, Uint8List> get writeTransformer =>
      config.writeTransformer;

  SxwBluetoothDevice(this.debugLabel, this.device);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is SxwBluetoothDevice &&
          runtimeType == other.runtimeType &&
          device == other.device;

  @override
  int get hashCode => device.hashCode;

  void disconnect();

  Future<void> writeData(Uint8List data) async {
    if (canUse) {
      _realWrite(data);
    }
  }

  Future<void> _realWrite(Uint8List data);

  StreamController<Uint8List> _dataController = StreamController.broadcast();

  Stream<Uint8List> get receiveStream => _dataController.stream;

  void onReceive(Uint8List data) {
    _dataController.add(data);
  }

  void dispose() {
    _dataController.close();
  }
}
